package com.example.config;

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import org.glassfish.jersey.client.ClientConfig;
import org.glassfish.jersey.client.ClientProperties;
import org.glassfish.jersey.client.rx.RxClient;
import org.glassfish.jersey.client.rx.rxjava.RxObservable;
import org.glassfish.jersey.client.rx.rxjava.RxObservableInvoker;
import org.glassfish.jersey.grizzly.connector.GrizzlyConnectorProvider;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import javax.ws.rs.client.ClientBuilder;
import java.util.concurrent.Executor;

@Configuration
public class AppConfiguration {

    @Value("${rxjava.clientTimeout}")
    private int clientTimeout;
    @Value("${rxjava.asyncThreadPoolSize}")
    private int asyncThreadPoolSize;

    @Bean
    public RxClient<RxObservableInvoker> rxClient(){


        /**
         *jersey the timeout value should be higher then the hystrix timeout setting
         */
        return RxObservable.from(ClientBuilder.newClient(new ClientConfig()
                    .property(ClientProperties.READ_TIMEOUT,this.clientTimeout)
                    .property(ClientProperties.ASYNC_THREADPOOL_SIZE,this.asyncThreadPoolSize)
                    .property(ClientProperties.CONNECT_TIMEOUT,this.clientTimeout)
                    )
            );


//            return RxObservable.from(ClientBuilder.newClient(new ClientConfig()
//                            .connectorProvider(new GrizzlyConnectorProvider())
//                            .property(ClientProperties.READ_TIMEOUT,this.clientTimeout)
//                            .property(ClientProperties.CONNECT_TIMEOUT,this.clientTimeout)
//                    )
//            );

    }


    @Bean(name="AsyncTestExecuter")
    public Executor getAsyncTestExecuter(){
        return getThreadPoolTaskExecutor(1000,10,25,"asyncTestExecuter");
    }

    private ThreadPoolTaskExecutor getThreadPoolTaskExecutor(final int queueCapacity,final int corePoolSize,final int maxPoolSize,final String threadname) {

        ThreadPoolTaskExecutor threadPoolTaskExecutor=new ThreadPoolTaskExecutor();
        threadPoolTaskExecutor.setQueueCapacity(queueCapacity);
        threadPoolTaskExecutor.setCorePoolSize(corePoolSize);
        threadPoolTaskExecutor.setMaxPoolSize(maxPoolSize);
        threadPoolTaskExecutor.setThreadFactory(new ThreadFactoryBuilder().setNameFormat(threadname+"-%d").build());
        return threadPoolTaskExecutor;
    }
}
